
const mysql = require('mysql');
const fs = require('fs');
const { readJsonConfigCache, extractErrorInfo } = require('./utils');
const sqlite3 = require('sqlite3').verbose();

var connection = undefined;
var dbType = 'sqlite'
/**
 * 初始化数据库链接
 */
async function initConnection(type) {
    dbType = type;
    if (dbType == 'mysql') {
        var jsonConfig = readJsonConfigCache("common.config.json")
        if (jsonConfig.db) {
            // var conn = mysql.createConnection(dbConfig);
            var pool = mysql.createPool(jsonConfig.db);
            // pool.connect()
            connection = pool;
            return connection;
        } else {
            return false;
        }
    } else if (dbType == 'sqlite') {
        connection = await initSqlLite();
        return connection;
    }
}

async function initSqlLite() {
    connection = new sqlite3.Database(__dirname + "/../../data/spider.db", function (err) {
        if (err) {
            console.log("初始化sqlite数据错误！", err);
            throw err;
        }
    });
    // 检查数据库表结构是否正常，如果未创建表，则创建表
    var existTable = await existTableStruct()
    if (!(existTable)) {
        var result = await initTableStruct();
        if (result.success) {
            console.log("初始化" + dbType + "数据库表结构成功！");
        } else {
            console.log("初始化" + dbType + "数据库表结构失败！" + result.error);
        }
    }
    return connection;
}

async function existTableStruct() {
    var result = await dbQuery("select 1 from spider_task limit 0,1")
    return result.success;
}

async function initTableStruct() {
    var initSql = fs.readFileSync(__dirname + "/../../data/" + dbType + ".sql", { encoding: 'utf-8' });
    var result = await dbQuery(initSql)
    return result;
}
/**
 * 数据库查询
 * 
 * @param {*} sql 
 * @param {*} params 
 * @returns Promise
 */
async function dbQuery(sql, params) {
    if (dbType == 'mysql') {
        return await new Promise((resolve, reject) => {
            try {
                connection.query(sql, params, function (error, results, fields) {
                    if (error) {
                        resolve({ success: false, error: error });
                        return;
                    }
                    resolve({ success: true, data: results });
                });
            } catch (e) {
                resolve({ success: false, error: e })
            }
        });
    } else if (dbType == 'sqlite') {
        sql = sql.replace(/NOW\(\)/g, "strftime('%Y-%m-%d %H:%M:%S','now','localtime')")
        return await new Promise((resolve, reject) => {
            try {
                // 多条sql
                var count = (sql.length-sql.replace(/;/g,'').length);
                if (count > 1) {
                    connection.exec(sql, function (error, results, fields) {
                        if (error) {
                            resolve({ success: false, error: error });
                            return;
                        }
                        results.affectedRows = this.changes;   
                        resolve({ success: true, data: results });
                    });
                } else {
                    if(sql.indexOf("update") == 0){
                        connection.run(sql, params, function (error, results, fields) {
                            if (error) {
                                resolve({ success: false, error: error });
                                return;
                            }
                            results = {};
                            results.affectedRows = this.changes;   
                            resolve({ success: true, data: results });
                        });
                    } else {
                        connection.all(sql, params, function (error, results, fields) {
                            if (error) {
                                resolve({ success: false, error: error });
                                return;
                            }
                            results.affectedRows = this.changes;   
                            resolve({ success: true, data: results });
                        });
                    }
                }
            } catch (e) {
                resolve({ success: false, error: e })
            }
        });
    }
}

module.exports = {
    initConnection: initConnection,
    dbQuery: dbQuery,
}

